package com.xiaoye.digitaltwin.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.xiaoye.digitaltwin.common.R;
import com.xiaoye.digitaltwin.entity.Student;
import com.xiaoye.digitaltwin.entity.Waiya;
import com.xiaoye.digitaltwin.service.StudentService;
import com.xiaoye.digitaltwin.service.WaiyaService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.DecimalFormat;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

/**
 * 外压实验表
 * <p>
 * 外压实验表 前端控制器
 * </p>
 *
 * @author xiaoye
 * @since 2023-04-01
 */
@Slf4j
@RestController
@RequestMapping("/waiya")
public class WaiyaController {

    @Autowired
    private WaiyaService waiyaService;

    @Autowired
    private StudentService studentService;

    @Value("${digital.path.waiya.basepath}")
    private String basePath;

    //学生上传报告所在路径
    @Value("${digital.path.waiya.report}")
    private String uploadReports;

    /**
     *
     * @param waiya
     * @param request
     * @return
     */
    @PostMapping("/compute")
    public R<String> handlerData(@RequestBody Waiya waiya, HttpServletRequest request){
        //对数据进行非空校验
        String checked = waiyaService.check(waiya);
        if(!checked.equals("通过")){
            return R.error(checked);
        }

        //前面还需要求出的试件长度和平均外径确定文件夹
        //  试件长度/平均外径/试件的长度—试件的平均外径-试件壁厚—初始缺陷

        //文件夹命名规则为“试件的长度—试件的平均外径-试件壁厚—初始缺陷”，
        Double length = waiya.getLength();
        Double outerAve = (waiya.getOuterMax() + waiya.getOuterMin()) / 2;
        Double wallThick = waiya.getWallThick();
        Double initDefect = waiya.getInitDefect();
        Double stress = waiya.getStress();

        String formatLen = formatLength(length);
        String formatOuter = formatAveOuter(outerAve);
        String formatWallThick  = formatWallThick(wallThick);
        String formatInitDefect = formatInitDefect(initDefect);
        String formatStress = formatStress(stress);


        //  试件长度/平均外径/试件的长度—试件的平均外径-试件壁厚—初始缺陷
        String folder = formatLen + File.separator + formatOuter + File.separator +
                formatLen + "-" + formatOuter + "-" + formatWallThick + "-"
                + formatInitDefect;


        //失稳模态图
        String unstablemodal = folder + File.separator + "shiwenmotai.jpeg";

        //试件模态变化图
        String modalChange = folder + File.separator + "weiyibianhua" + File.separator +
                "shiwen" + formatStress + ".jpeg";
        //载荷-位移曲线  是视频文件
//        String loadDisplacement = folder + File.separator + "载荷—位移变化曲线.avi";
        String loadDisplacement = folder + File.separator + "载荷—位移数据列表.txt";
        String download = folder + File.separator + "下载文件.zip";


        String stuId = request.getSession().getAttribute("studentId").toString();
        //获取学生学号
        Student stu = studentService.getById(stuId);
        String stuNo = stu.getStuNo();

        waiya.setUnstablemodal(unstablemodal);
        waiya.setModalChange(modalChange);
        waiya.setLoadDisplacement(loadDisplacement);
        waiya.setDownload(download);
        waiya.setStuNo(stuNo);

        //查询外压表中是否存在数据 一个学生对应一条数据，已存在的话就需要更新
        LambdaQueryWrapper<Waiya> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Waiya::getStuNo,stuNo);
        Waiya waiyaStu = waiyaService.getOne(queryWrapper);
        if (waiyaStu == null){
            waiyaService.save(waiya);
        }else {
            waiyaStu.setUnstablemodal(unstablemodal);
            waiyaStu.setModalChange(modalChange);
            waiyaStu.setLoadDisplacement(loadDisplacement);
            waiyaStu.setDownload(download);
            waiyaService.updateById(waiyaStu);
        }
        return R.success("成功");
    }


    /**
     * 学生上传实验报告
     * @param request
     * @param file
     * @return
     */
    @PostMapping("/report")
    public R<String> uploadRepoet(HttpServletRequest request, MultipartFile file){
        //获取原始文件名
        String originalFilename = file.getOriginalFilename();
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));

        String studentId = request.getSession().getAttribute("studentId").toString();
        //查询学生学号
        Student stu = studentService.getById(studentId);
        String stuNo = stu.getStuNo();

        //将学号与文件后缀名拼接 组成唯一标识
        String reportname = stuNo + suffix;

        //将上传的文件保存在指定路径
        File dir = new File(uploadReports);
        if(!dir.exists()){
            //目录不存在，需要创建
            dir.mkdirs();
        }
        try {
            //将临时文件转存到指定位置
            file.transferTo(new File(uploadReports + reportname));
        } catch (IOException e) {
            e.printStackTrace();
            return R.error("报告上传失败");
        }

        LambdaUpdateWrapper<Waiya> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Waiya::getStuNo,stuNo);
        updateWrapper.set(Waiya::getReport,reportname);
        waiyaService.update(updateWrapper);
        return R.success("文件上传成功");
    }
    /**
     * 返回失稳模态图
     * @param request
     * @return
     */
    @GetMapping("/shiwen")
    public R<String> returnShiwen(HttpServletRequest request){
        String stuId = request.getSession().getAttribute("studentId").toString();
        //获取学生学号
        Student stu = studentService.getById(stuId);
        String stuNo = stu.getStuNo();

        //从外压表查询该学生对应记录
        LambdaQueryWrapper<Waiya> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Waiya::getStuNo,stuNo);
        Waiya waiyaStu = waiyaService.getOne(queryWrapper);

        //出现异常导致外压表没有数据
        if (waiyaStu == null)
            return R.error("数据库暂无数据");

        String shiwenPic = waiyaStu.getModalChange();
        return R.success(shiwenPic);
    }

    /**
     * 返回事件模态变化图
     * @param request
     * @return
     */
    @GetMapping("/motai")
    public R<String> returnMotai(HttpServletRequest request){
        String stuId = request.getSession().getAttribute("studentId").toString();
        //获取学生学号
        Student stu = studentService.getById(stuId);
        String stuNo = stu.getStuNo();

        //从外压表查询该学生对应记录
        LambdaQueryWrapper<Waiya> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Waiya::getStuNo,stuNo);
        Waiya waiyaStu = waiyaService.getOne(queryWrapper);

        //出现异常导致外压表没有数据
        if (waiyaStu == null)
            return R.error("数据库暂无数据");

        String motaiPic = waiyaStu.getUnstablemodal();
        return R.success(motaiPic);
    }

    /**
     * 返回载荷一位移曲线
     *
     * @param request
     * @return
     */
    @GetMapping("/zaihe")
    public R<Map<String, String>> returnZaihe(HttpServletRequest request) throws FileNotFoundException {
        String stuId = request.getSession().getAttribute("studentId").toString();
        //获取学生学号
        Student stu = studentService.getById(stuId);
        String stuNo = stu.getStuNo();

        //从外压表查询该学生对应记录
        LambdaQueryWrapper<Waiya> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Waiya::getStuNo,stuNo);
        Waiya waiyaStu = waiyaService.getOne(queryWrapper);

        //出现异常导致外压表没有数据
        if (waiyaStu == null)
            return R.error("数据库暂无数据");

        String baseUrl = "E:\\Project\\DigitalTwinPic\\waiya\\";
        String zaihePic = waiyaStu.getLoadDisplacement();
        String filePath = baseUrl + zaihePic;
//        String filePath = "E:\\Project\\DigitalTwinPic\\waiya\\127.6\\52.5\\127.6-52.5-0.24-0.01\\载荷—位移数据列表.txt";
        double[] a;
        double[] b;


            File file = new File(filePath);
            Scanner scanner = new Scanner(file);

            int lines = 0;
            while (scanner.hasNextLine()) {
                scanner.nextLine();
                lines++;
            }

            a = new double[lines];
            b = new double[lines];

            scanner = new Scanner(file);
            int index = 0;

            while (scanner.hasNextLine()) {
                String line = scanner.nextLine();

                if (!line.isEmpty()) {
                    String[] values = line.split(" ");

                    a[index] = Double.parseDouble(values[0]);
                    b[index] = Double.parseDouble(values[1]);

                    index++;
                }
            }

            // 将数组转换为字符串形式
            String arrayAStr = Arrays.toString(a);
            String arrayBStr = Arrays.toString(b);

            // 创建 Map 并返回
            Map<String, String> resultMap = new HashMap<>();
            resultMap.put("arrayB", arrayBStr);
            resultMap.put("arrayA", arrayAStr);

            return R.success(resultMap);



//        return R.success(zaihePic);
    }

    /**
     * 学生下载实验数据
     * @param request
     * @param response
     */
    @GetMapping("/data")
    public void downloadData(HttpServletRequest request, HttpServletResponse response){
        String stuId = request.getSession().getAttribute("studentId").toString();
        //获取学生学号
        Student stu = studentService.getById(stuId);
        String stuNo = stu.getStuNo();

        LambdaQueryWrapper<Waiya> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Waiya::getStuNo,stuNo);
        Waiya waiyaStu = waiyaService.getOne(queryWrapper);
        if(waiyaStu == null){
            return;
        }
        String download = waiyaStu.getDownload();

        //如果表中无数据
        if(download == null){
            //说明还没有开始实验
            return ;
        }else{
            try {
                //输入流，通过输入流读取文件内容
                FileInputStream fileInputStream = new FileInputStream(new File(basePath + download));

                //输出流，通过输出流将文件写回浏览器
                ServletOutputStream outputStream = response.getOutputStream();
                response.setContentType("application/octet-stream");
                response.setHeader("Content-Disposition", "attachment; filename=" + download);

                int len = 0;
                byte[] bytes = new byte[1024];
                while ((len = fileInputStream.read(bytes)) != -1){
                    outputStream.write(bytes,0,len);
                    outputStream.flush();
                }
                //关闭资源
                outputStream.close();
                fileInputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * 学生反馈信息
     * @param request
     * @param msg
     * @return
     */
    @PostMapping("/feedback")
    public R<String> feedback(HttpServletRequest request, String msg){
        return null;
    }


    /**
     * 格式化试件长度
     * 试件长度三种情况
     * @param length
     * @return
     */
    public String formatLength(double length){
        if(length >= 127.6 && length < 127.7){
            return "127.6";
        }else if(length >= 127.7 && length < 127.9){
            return "127.8";
        }else
            return "128.0";
    }

    /**
     * 格式化平均外径
     * @param outerAve
     * @return
     */
    public String formatAveOuter(double outerAve){
        if(outerAve >= 52.5 && outerAve < 52.575){
            return "52.5";
        }else if(outerAve >= 52.575 && outerAve < 52.725){
            return "52.65";
        }else
            return "52.8";
    }

    /**
     * 格式化壁厚
     * @param wallThick
     * @return
     */
    public String formatWallThick(Double wallThick){
        if (wallThick >= 0.24 && wallThick < 0.245) {
            return "0.24";
        }else if(wallThick >= 0.245 && wallThick < 0.255){
            return "0.25";
        }else
            return "0.26";
    }

    /**
     * 格式化初始缺陷
     * @param initDefect
     * @return
     */
    public String formatInitDefect(Double initDefect){
        if (initDefect >= 0.01 && initDefect < 0.02){
            return "0.01";
        }else if(initDefect >= 0.02 && initDefect < 0.04){
            return "0.03";
        }else
            return "0.05";
    }

    /**
     * 格式化压力值
     * @param stress
     * @return
     */
    public String formatStress(Double stress){
        //如果压力值过小  无法舍入到最小值0.01的话，直接返回0.01  （后续如果有新要求的话，可以变动）
        if(stress < 0.005){
            return "0.01";
        }
        //先对数据进行四舍五入保留两位小数
        DecimalFormat decimalFormat = new DecimalFormat("#.00");
        double newStress = Double.parseDouble(decimalFormat.format(stress));
        if (stress == 0.1 || stress == 0.2 || stress == 0.3) {
            return Double.toString(newStress) + "0";
        }
        return Double.toString(newStress);
    }
}
